/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { Chain, Dns, Interceptor, Request, Response, Utils } from '@ohos/httpclient';
import connection from '@ohos.net.connection';
import { BusinessError } from '@ohos/httpclient/src/main/ets/http';

export class CustomDns implements Dns {
  async lookup(hostname: string): Promise<Array<connection.NetAddress>> {
    return await new Promise((resolve, reject) => {
      connection.getAddressesByName(hostname).then((netAddress) => {
        console.info('netAddress = ' + JSON.stringify(netAddress))
        resolve(netAddress)
      }).catch((err: BusinessError) => {
        reject(err)
      });
    })
  }
}

export class CustomInterceptor implements Interceptor {
  intercept(chain: Chain): Promise<Response> {
    return new Promise<Response>((resolve, reject) => {
      let originRequest: Request = chain.requestI();
      let url: string = originRequest.url.getUrl();
      let host: string = Utils.getDomainOrIp(url)
      connection.getAddressesByName(host).then((netAddress) => {
        let newRequest = originRequest.newBuilder();
        if (!!netAddress) {
          if (Utils.isIPv6(netAddress[0].address)) {
            let ipv4Address: Array<connection.NetAddress> = [];
            let ipv6Address: Array<connection.NetAddress> = [];
            for (let i = 0, len = netAddress.length; i < len; i++) {
              if (Utils.isIPv6(netAddress[i].address)) {
                ipv6Address.push(netAddress[i])
              } else {
                ipv4Address.push(netAddress[i])
              }
            }
            netAddress = [];
            netAddress = netAddress.concat(ipv4Address).concat(ipv6Address)
          }

          url = url.replace(host, netAddress[0].address)
          newRequest.url(url)
        }
        newRequest.dnsInterceptor()
        let newResponse: Promise<Response> = chain.proceedI(newRequest.build())
        resolve(newResponse)
      }).catch((err: BusinessError) => {
        reject(err)
      });
    })
  }
}